<template id="pdfToImage">
    <!-- pdf转图片 -->
    <div class="pdf-to-image">
        <i v-show="isLoading" class="iconfont icon-tupian"><!--图片加载中--></i>
        <div v-show="!isLoading" class="image-container" id="pdf-container"></div>
    </div>
</template>

<script>
    const pdfToImage = {
        template: '#pdfToImage',
        props: {
            pdfPath: {type: String,},
            scale: {type: Number, default: 2}
        },
        data() {
            return {
                isLoading: true,
            };
        },
        methods: {
            // 初始化 PDF 转图片的方法
            async init() {
                this.isLoading = true;
                try {
                    // 设置 pdf.js worker 的源路径
                    pdfjsLib.GlobalWorkerOptions.workerSrc = "/vue-page/v2/resources/js/plug-in/pdf/pdf.worker.min.js";

                    // 获取 PDF 文件的 URL，优先使用传入的 props，若未传入则使用默认值
                    const pdfUrl = this.pdfPath;

                    // 提高缩放比例，可根据实际情况调整
                    const scale = this.scale;

                    // 加载 PDF 文件
                    const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
                    const numPages = pdf.numPages;
                    const pdfContainer = document.getElementById("pdf-container");

                    // 存储每一页的 canvas
                    const pageCanvases = [];
                    let totalHeight = 0;
                    let maxWidth = 0;

                    // 遍历每一页并转换为 canvas
                    const loadPagePromises = [];
                    for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
                        const pagePromise = this.renderPageToCanvas(pdf, pageNumber, scale);
                        loadPagePromises.push(pagePromise);
                    }

                    // 等待所有页面渲染完成
                    const renderedPages = await Promise.all(loadPagePromises);
                    renderedPages.forEach((canvas) => {
                        pageCanvases.push(canvas);
                        totalHeight += canvas.height;
                        maxWidth = Math.max(maxWidth, canvas.width);
                    });

                    // 将所有页面合并到一个大的 canvas 上
                    const combinedCanvas = this.combineCanvases(pageCanvases, totalHeight, maxWidth);

                    // 创建图片元素并添加到容器中
                    const img = document.createElement("img");
                    img.src = combinedCanvas.toDataURL("image/png");
                    pdfContainer.appendChild(img);
                    this.isLoading = false;
                } catch (error) {
                    console.error('PDF 转图片过程中出现错误:', error);
                }
            },
            // 将单页 PDF 渲染到 canvas 的方法
            async renderPageToCanvas(pdf, pageNumber, scale) {
                const page = await pdf.getPage(pageNumber);
                const viewport = page.getViewport({scale: scale});

                const canvas = document.createElement("canvas");
                const context = canvas.getContext("2d");
                canvas.height = viewport.height;
                canvas.width = viewport.width;

                // 提高 DPI
                const devicePixelRatio = window.devicePixelRatio || 1;
                canvas.style.width = canvas.width + 'px';
                canvas.style.height = canvas.height + 'px';
                canvas.width = canvas.width * devicePixelRatio;
                canvas.height = canvas.height * devicePixelRatio;
                context.scale(devicePixelRatio, devicePixelRatio);

                const renderContext = {
                    canvasContext: context,
                    viewport: viewport,
                };

                await page.render(renderContext).promise;
                return canvas;
            },
            // 合并所有 canvas 到一个大 canvas 的方法
            combineCanvases(pageCanvases, totalHeight, maxWidth) {
                const combinedCanvas = document.createElement("canvas");
                const combinedContext = combinedCanvas.getContext("2d");
                combinedCanvas.height = totalHeight;
                combinedCanvas.width = maxWidth;

                let currentY = 0;
                for (let i = 0; i < pageCanvases.length; i++) {
                    const pageCanvas = pageCanvases[i];
                    combinedContext.drawImage(pageCanvas, 0, currentY);
                    currentY += pageCanvas.height;
                }

                return combinedCanvas;
            }
        },
        mounted() {
            // 动态加载 pdf.js 和 pdf.worker.min.js
            Promise.all([
                wzbRequire.require("/vue-page/v2/resources/js/plug-in/pdf/pdf.min.js"),
                wzbRequire.require("/vue-page/v2/resources/js/plug-in/pdf/pdf.worker.min.js"),
            ]).then(() => {
                if (this.pdfPath) this.init();
            }).catch((error) => {
                console.error('加载 PDF 相关脚本时出现错误:', error);
            });
        },
        watch: {
            pdfPath(newValue, oldValue) {
                if (newValue) this.init();
            }
        }
    };
</script>

<style>
    .pdf-to-image {
        width: 100%;
        height: 100%;
    }

    .pdf-to-image > i {
        height: 100%;
        width: 100%;
        background: #f7f7f8;
        overflow: hidden;
        color: gray;
        font-size: 60px;
        display: flex;
        align-content: center;
        align-items: center;
        justify-content: center;
    }

    .image-container {
        width: 100%;
        height: 100%;
        /*background: #f0f0f0;*/
        position: relative;
    }

    .image-container > img {
        width: 100%;
        object-fit: contain;
        position: absolute;
        top: 0;
        left: 0;
    }

</style>